using System;
using System.Collections;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.Data;
using System.Xml;
using System.IO;
using System.Linq;

namespace Alex.Library.Cloud.VMWare.V51.Util
{
    /// <summary>
    /// VersionUtil that determines the NameSpace And Supported Versions
    /// </summary>
    public class VersionUtil
    {
        public static List<string> GetSupportedVersions(String urlString)
        {
            HttpWebRequest request;
            HttpWebResponse resp;
            string respString;
            string targetNameSpace = "";

            XmlDocument versionXML = new XmlDocument();
            List<string> appVersionList = new List<string>();

            string wsdlUrlString = urlString.Substring(0, urlString.IndexOf("/sdk") + 4)
                                     + "/vimService?wsdl";
            string vimServiceXmlUrlString = urlString.Substring(0, urlString.IndexOf("/sdk") + 4)
                                     + "/vimServiceVersions.xml";
            try
            {
                bool isServiceXmlExists = true;
                try
                {
                    request = (HttpWebRequest)WebRequest.Create(vimServiceXmlUrlString);
                    request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None;
                    request.ContentType = "text/xml";
                    resp = (HttpWebResponse)request.GetResponse();
                    StreamReader sr = new StreamReader(resp.GetResponseStream(), Encoding.ASCII);
                    respString = sr.ReadToEnd();
                    targetNameSpace = "urn:vim25";
                    appVersionList = GetAPIVersions(respString);
                }
                catch (WebException e)
                {
                    if (e.Message.Contains("404"))
                    {
                        isServiceXmlExists = false;
                    }
                }
                if (!isServiceXmlExists)
                {
                    request = (HttpWebRequest)WebRequest.Create(wsdlUrlString);
                    request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None;
                    request.ContentType = "text/xml";
                    resp = (HttpWebResponse)request.GetResponse();
                    StreamReader sr = new StreamReader(resp.GetResponseStream(), Encoding.ASCII);
                    respString = sr.ReadToEnd();
                    versionXML.LoadXml(respString);
                    targetNameSpace = versionXML.DocumentElement.GetAttribute("targetNamespace");

                    if (targetNameSpace.Equals("urn:vim25Service"))
                    {
                        appVersionList.Add("2.5");
                    }
                    else
                    {
                        appVersionList.Add("2.0");
                    }
                }
                return appVersionList;
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public static List<string> GetAPIVersions(string respString)
        {
            string targetNameSpace;
            string name_NODE;
            string version_NODE;
            XmlDocument versionXML = new XmlDocument();
            XmlNodeList versionNodeList;
            List<string> priorVersionsList = new List<string>();
            List<string> appVersionList = new List<string>();
            versionXML = new XmlDocument();
            versionXML.LoadXml(respString);
            targetNameSpace = "urn:vim25";
            name_NODE = "/namespaces/namespace/name";
            if (versionXML.SelectSingleNode(name_NODE).InnerText.Equals(targetNameSpace))
            {
                version_NODE = "/namespaces/namespace/priorVersions/version";
                versionNodeList = versionXML.SelectNodes(version_NODE);

                foreach (XmlNode pversionNode in versionNodeList)
                {
                    priorVersionsList.Add(pversionNode.InnerText);
                }
                version_NODE = "/namespaces/namespace/version";
                XmlNode versionNode = versionXML.SelectSingleNode(version_NODE);
                priorVersionsList.Add(versionNode.InnerText);
            }
            return priorVersionsList;
        }

        public static vim25Api.ManagedObjectReference ConvertManagedObjectReference(
            vimApi.ManagedObjectReference mor)
        {
            return new vim25Api.ManagedObjectReference
            {
                type = mor.type,
                Value = mor.Value
            };
        }

        public static bool isApiVersionSupported(List<string> apiVersions, string version)
        {
            return apiVersions.Exists(v => v.Equals(version));
        }
    }
}
